본문으로 건너뛰기

[Part3] Ch5. Prototype

5.1 [[Prototype]]

  • 객체는 [[Prototype]]이라는 내부 프로퍼티로 다른 객체를 참조하는 링크를 가진다.
  • 객체를 생성할 때 이 링크가 설정되며, 해당 객체에서 프로퍼티를 찾을 수 없을 때 이 링크를 따라 탐색된다.
var anotherObject = {
a: 2
};

var myObject = Object.create(anotherObject);
console.log(myObject.a); // 2

for...in & in 연산자

for (var k in myObject) {
console.log(`${k} 를 발견`);
}

"a" in myObject; // true

5.1.1 Object.prototype

  • [[Prototype]] 체인의 최상단은 Object.prototype이다.
  • 모든 객체는 Object.prototype을 상속한다.

5.1.2 프로퍼티 세팅과 가려짐 (Shadowing)

myObject.foo = "bar";
  • foo가 현재 객체에 없으면 [[Prototype]]을 탐색
  • 상위에서 foo가 있고:
    • writable: 가려짐 발생
    • non-writable: strict 모드에서는 에러
    • setter: setter 호출 (가려짐 아님)
var anotherObject = {
a: 2
};
var myObject = Object.create(anotherObject);

myObject.a++; // 암시적 가려짐

console.log(anotherObject.a); // 2
console.log(myObject.a); // 3
  • myObjecta를 갖지 않았지만, a++ 수행 시 새로 a를 생성하며 가림
  • Object.defineProperty()로 직접 정의 가능

→ 가려짐은 명시적 위임이 필요한 경우 문제를 야기할 수 있으며, 작동 위임(6장)으로 대체할 수 있다.


5.2 클래스

자바스크립트에서 클래스는 존재하지 않지만, 이를 흉내내는 방식이 있다.


5.2.1 클래스 함수

function Foo() {}

Foo.prototype; // {}

var a = new Foo();
Object.getPrototypeOf(a) === Foo.prototype; // true
  • new를 통해 Foo.prototypea[[Prototype]]이 연결된다.

→ 클래스는 복사 기반이 아니라 링크 기반 상속


차등 상속

  • 객체 간 차이를 기반으로 새로운 객체를 구성하는 방식
  • 중복보다 필요한 차이만 기술

5.2.2 생성자

function Foo() {
// ...
}

var a = new Foo();
a.constructor === Foo; // true
  • new는 함수 실행에 객체 생성 로직을 추가한 연산자
  • NothingSpecial() 같은 일반 함수도 new로 호출 시 객체 생성
function NothingSpecial() {
console.log('');
}

var a = new NothingSpecial(); // a: {}

→ 생성자라는 표현은 문법적으로 부정확할 수 있다


5.2.3 체계 예시

function Foo(name) {
this.name = name;
}

Foo.prototype.myName = function () {
return this.name;
};

var a = new Foo("a");
var b = new Foo("b");

console.log(a.myName()); // 'a'
console.log(b.myName()); // 'b'
  • a, b는 각각 Foo로부터 생성된 인스턴스
  • myName 메서드는 Foo.prototype에 존재

클래스지향의 꼼수이며 진정한 객체 연결(OLOO)은 이후 장에서 다룬다